﻿using System;
using System.Collections;
using System.ServiceProcess;
using System.Configuration.Install;
using System.Threading;

namespace Core
{
    public class WindowsServiceManager
    {
        #region 安装windows服务
        public static void InstallService(string serviceName, string filepath = "")
        {
            if (filepath == "")
            {
                filepath = GetAppPath();
            }

            ServiceController service = new ServiceController(serviceName);
            IDictionary stateSaver = new Hashtable();

            if (!IsServiceExisted(serviceName))
            {
                //Install Service  
                AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();
                myAssemblyInstaller.UseNewContext = true;
                myAssemblyInstaller.Path = filepath;
                myAssemblyInstaller.Install(stateSaver);
                myAssemblyInstaller.Commit(stateSaver);
                myAssemblyInstaller.Dispose();
                //--Start Service  
                service.Start();
            }
            else
            {
                if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
                {
                    service.Start();
                }
            }

        }

        #endregion

        #region 卸载windows服务

        public static void UnInstallService(string serviceName, string filepath = "")
        {
            if (filepath == "")
            {
                filepath = GetAppPath();
            }

            if (IsServiceExisted(serviceName))
            {
                //UnInstall Service  
                AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();
                myAssemblyInstaller.UseNewContext = true;
                myAssemblyInstaller.Path = filepath;
                myAssemblyInstaller.Uninstall(null);
                myAssemblyInstaller.Dispose();
            }

        }

        #endregion

        #region 判断window服务是否存在

        public static bool IsServiceExisted(string serviceName, string filepath = "")
        {
            if (filepath == "")
            {
                filepath = GetAppPath();
            }

            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController s in services)
            {
                if (s.ServiceName == serviceName)
                {
                    return true;
                }
            }

            return false;
        }

        #endregion

        #region 判断window服务是否启动

        /// <summary>  
        /// 判断某个Windows服务是否启动
        /// </summary>  
        /// <returns></returns>  
        public static bool IsServiceStarted(string serviceName)
        {
            ServiceController psc = new ServiceController(serviceName);
            bool bStartStatus = false;

            try
            {
                if (!psc.Status.Equals(ServiceControllerStatus.Stopped))
                {
                    bStartStatus = true;
                }

                return bStartStatus;
            }

            catch
            {
                return false;
            }

        }

        #endregion

        #region 启动服务
        public static void StartService(string serviceName, string filepath = "")
        {
            if (!IsServiceExisted(serviceName))
            {
                InstallService(serviceName, filepath);
            }

            System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

            if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
            {
                service.Start();
            }
        }

        #endregion

        #region 停止服务
        public static void StopService(string serviceName)
        {
            try
            {
                if (IsServiceExisted(serviceName))
                {
                    System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);
                    if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                    {
                        service.Stop();
                        for (int i = 0; i < 60; i++)
                        {
                            service.Refresh();
                            System.Threading.Thread.Sleep(1000);
                            if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.errorlog(ex);
            }
        }


        public static string GetAppPath()
        {
            string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
            path = path.Replace("vshost.", "");
            return path;
        }

        #endregion

        #region 重启服务
        public static void ReStartService(string serviceName, string filepath = "")
        {
            if (!IsServiceExisted(serviceName))
            {
                InstallService(serviceName, filepath);
            }

            System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

            if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
            {
                StartService(serviceName);
            }
            else
            {
                if (service.CanStop)
                {
                    StopService(serviceName);
                    StartService(serviceName);
                }
            }
        }
        #endregion
    }
}